package com.detech.sboh.base.hibernate.custom;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManagerFactory;
import java.util.List;

@Repository
public class CustomDAO {

	@Autowired
	private EntityManagerFactory entityManagerFactory;

	public Session getSession() {
		return entityManagerFactory.unwrap(SessionFactory.class).openSession();
	}

	public Session getCurrentSession() {
		return entityManagerFactory.unwrap(SessionFactory.class).getCurrentSession();
	}

	public void save(Object transientInstance) {
		try {
			getCurrentSession().save(transientInstance);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public void saveOrUpdate(Object instance) {
		try {
			getCurrentSession().saveOrUpdate(instance);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public void update(Object instance) {
		this.getCurrentSession().update(instance);
	}

	public void delete(Object persistentInstance) {
		try {
			getCurrentSession().delete(persistentInstance);
		} catch (RuntimeException re) {
			throw re;
		}
	}

	public List find(String hql, Object val) {
		hql = sqlToHibernate5(hql);
		Query query = this.getCurrentSession().createQuery(hql);
		if (val != null) {
			query.setParameter(0, val);
		}
		return query.list();
	}

	public List find(String hql, Object... values) {
		hql = sqlToHibernate5(hql);
		Query query = this.getCurrentSession().createQuery(hql);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				query.setParameter(i, values[i]);
			}
		}
		return query.list();
	}

	public List find(String hql, List params) {
		hql = sqlToHibernate5(hql);
		Query query = this.getCurrentSession().createQuery(hql);
		if(params!=null && params.size()>0){
			for(int i=0;i<params.size();i++){
				query.setParameter(i, params.get(i));
			}
		}
		return query.list();
	}

	public int bulkUpdate(String hql, Object val) {
		hql = sqlToHibernate5(hql);
		Query query = this.getCurrentSession().createQuery(hql);
		if (val != null) {
			query.setParameter(0, val);
		}
		return query.executeUpdate();
	}

	public int bulkUpdate(String hql, Object... vals) {
		hql = sqlToHibernate5(hql);
		Query query = this.getCurrentSession().createQuery(hql);
		if (vals != null) {
			for (int i = 0; i < vals.length; i++) {
				query.setParameter(i, vals[i]);
			}
		}
		return query.executeUpdate();
	}

	public int bulkUpdate(String hql, List params) {
		hql = sqlToHibernate5(hql);
		Query query = this.getCurrentSession().createQuery(hql);
		if (params != null && params.size()>0) {
			for (int i = 0; i < params.size(); i++) {
				query.setParameter(i, params.get(i));
			}
		}
		return query.executeUpdate();
	}

	public String sqlToHibernate5(String sql) {
		String hqlTmp = "";
		int firstPos = -1;
		int index = sql.indexOf("?",firstPos);
		if(index < 0){
			return sql;
		}
		int count = 0;
		while (index>=0){
			hqlTmp = hqlTmp + sql.substring(firstPos+1,index) + "?" + count;
			count++;
			firstPos = index;
			index = sql.indexOf("?",index + 1);
		}
		return hqlTmp;
	}

}
